package com.shell.customer.base.service.impl;

import com.shell.bee.acct.transaction.vo.AcctInfo;
import com.shell.bee.base.exception.UnCheckException;
import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.persistence.annotation.Pagination;
import com.shell.bee.persistence.model.PageLimit;
import com.shell.bee.persistence.service.impl.PersistentServiceImpl;
import com.shell.customer.accreditation.vo.AuthenticatingCusVo;
import com.shell.customer.base.dao.CusRecDao;
import com.shell.customer.base.service.CusAcctService;
import com.shell.customer.base.service.CusRecService;
import com.shell.customer.base.vo.CusRecVo;
import com.shell.customer.po.CusAcct;
import com.shell.customer.po.CusRec;
import com.shell.customer.trade.service.CustomerAcctService;
import com.shell.feign.PubDictionaryFeign;
import com.shell.feign.PubOrganFeign;
import com.shell.feign.PubRoleFeign;
import com.shell.feign.PubUserFeign;
import com.shell.feign.UserOrganFeign;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.governor.authorization.po.PubRole;
import com.shell.governor.modules.po.PubDictionary;
import com.shell.governor.organization.po.PubOrgan;
import com.shell.governor.organization.vo.PubOrganVo;
import com.shell.governor.user.po.PubUser;
import com.shell.governor.user.po.PubUserOrgan;
import com.shell.governor.user.vo.PubUserVo;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service("customerCService")
public class CusRecServiceImpl extends PersistentServiceImpl<CusRec> implements CusRecService {
	@Autowired
	private CusRecDao cusRecDao;
	@Autowired
	private PubUserFeign pubUserFeign;
	@Autowired
	private PubOrganFeign pubOrganFeign;
	@Autowired
	private PubRoleFeign pubRoleFeign;
	@Autowired
	private UserOrganFeign userOrganFeign;
	@Autowired
	private PubDictionaryFeign pubDictionaryFeign;
	@Autowired
	private CusAcctService pubCusAcctService;
	@Autowired
	private CustomerAcctService customerAcctService;

	public CusRecVo selectEnterpriseInfo(String curEntId) {
		CusRecVo cusRecVo = new CusRecVo();
		CusRec customer = (CusRec) selectByKey(curEntId);
		if (customer == null) {
			return null;
		}
		BeanUtils.copyProperties(customer, cusRecVo);
		PubUser user = this.pubUserFeign.selectByKey(customer.getContactorId());
		cusRecVo.setCertNo(user.getCertNo());
		cusRecVo.setCertType(user.getCertType());
		cusRecVo.setContactorName(user.getUserName());
		cusRecVo.setContactorPhone(user.getPhoneNo());
		return cusRecVo;
	}

	public int saveCustomer(CusRecVo customercVo) {
		int result = 0;
		if ((StringUtil.notEmpty(customercVo.getCusId()))
				&& (this.cusRecDao.selectByPrimaryKey(customercVo.getCusId().trim()) != null)) {
			throw new UnCheckException("����������������������");
		}
		checkSaveCusVo(customercVo);
		setPropety(customercVo);

		PubOrganVo organVo = packOrganVo(customercVo);

		PubUserVo user = setUserProperty(customercVo);

		result = save(customercVo);

		result = result > 0 ? this.pubOrganFeign.saveOrUpdateOrganRecord(organVo) : 0;

		result = result > 0 ? this.pubUserFeign.saveUser(user) : 0;
		if (result < 1) {
			throw new UnCheckException("������������������");
		}
		return result;
	}

	public boolean checkCustomer(String cusCode, String orgCode, String socCrCode) {
		CusRec customer = new CusRec();
		int result = 0;
		if (StringUtil.notTrimEmpty(cusCode)) {
			customer.setCusCode(cusCode);
			result = this.cusRecDao.selectCount(customer);
			customer.setCusCode(null);
		}
		if (StringUtil.notTrimEmpty(orgCode)) {
			customer.setOrgCode(orgCode);
			result = result == 0 ? this.cusRecDao.selectCount(customer) : 1;
			customer.setOrgCode(orgCode);
		}
		if (StringUtil.notTrimEmpty(socCrCode)) {
			customer.setSocCrCode(socCrCode);
			result = result == 0 ? this.cusRecDao.selectCount(customer) : 1;
			customer.setSocCrCode(null);
		}
		if (result > 0) {
			return true;
		}
		return false;
	}

	public int updateCustomer(CusRecVo customercVo) {
		int result = 0;
		PubOrganVo organVo = new PubOrganVo();
		PubUserVo user = new PubUserVo();
		if ("D".equals(customercVo.getCusState())) {
			customercVo = getCustomer(customercVo.getCusId());
			customercVo.setCusState("D");
		} else {
			checkSaveCusVo(customercVo);
		}
		organVo = packOrganVo(customercVo);

		user = packUserVo(customercVo);

		result = this.cusRecDao.updateByPrimaryKeySelective(customercVo);

		result = result > 0 ? this.pubOrganFeign.saveOrUpdateOrganRecord(organVo) : 0;

		result = result > 0 ? this.pubUserFeign.updateUser(user) : 0;
		if (result < 1) {
			throw new UnCheckException("������������������");
		}
		return result;
	}

	public CusRecVo getCustomer(String custId) {
		CusRecVo cusRecVo = new CusRecVo();
		CusRec customer = (CusRec) this.cusRecDao.selectByPrimaryKey(custId);
		if (customer == null) {
			return null;
		}
		BeanUtils.copyProperties(customer, cusRecVo);

		PubUser user = this.pubUserFeign.selectByKey(customer.getContactorId());
		cusRecVo.setCertNo(user.getCertNo());
		cusRecVo.setCertType(user.getCertType());
		cusRecVo.setContactorName(user.getUserName());
		cusRecVo.setContactorPhone(user.getPhoneNo());
		cusRecVo.setAdminEmail(user.getEmail());

		AcctInfo queryAcct = new AcctInfo();
		queryAcct.setCustId(custId);
		queryAcct.setUseCode("00");
		queryAcct.setAcctType("0");
		queryAcct.setAcctSts("N");
		List<AcctInfo> accts = this.customerAcctService.getAcctCardInfos(queryAcct);
		if ((accts != null) && (accts.size() > 0)) {
			CusAcct acct = new CusAcct();
			acct.setCusId(custId);
			acct.setAcctNo(((AcctInfo) accts.get(0)).getAcctNo());
			acct.setAcctType("0");
			acct.setAcctState("N");
			CusAcct cusAcct = (CusAcct) this.pubCusAcctService.selectOne(acct);
			cusRecVo.setCusAcct(cusAcct);
		}
		PubDictionary dict = this.pubDictionaryFeign.getDictionaryByCode(cusRecVo.getCusType());
		String roleStr = dict.getExtension2();
		if (StringUtil.notEmpty(roleStr)) {
			String[] roles = roleStr.split(",");
			List<PubUserVo> admins = this.pubUserFeign.selectUserByRoleCodeAndEntId(custId, roles[0]);
			String authFileRlatIds = "";
			for (PubUserVo admin : admins) {
				if (StringUtil.notEmpty(admin.getAuthFileRlatId())) {
					if (authFileRlatIds.equals("")) {
						authFileRlatIds = admin.getAuthFileRlatId();
					} else {
						authFileRlatIds = authFileRlatIds + "," + admin.getAuthFileRlatId();
					}
				}
			}
			cusRecVo.setAuthFileRlatIds(authFileRlatIds);
		}
		return cusRecVo;
	}

	@Pagination
	public List<CusRecVo> selectCustomerList(PageLimit limit, CusRecVo cusRecVo) {
		if (cusRecVo == null) {
			return null;
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getCusName())) {
			cusRecVo.setCusName(StringUtil.getParameterLike(cusRecVo.getCusName()));
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getCusCode())) {
			cusRecVo.setCusCode(StringUtil.getParameterLike(cusRecVo.getCusCode()));
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getLoginName())) {
			cusRecVo.setLoginName(StringUtil.getParameterLike(cusRecVo.getLoginName()));
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getLoginName())) {
			cusRecVo.setLoginName(StringUtil.getParameterLike(cusRecVo.getLoginName()));
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getSearchVuale())) {
			cusRecVo.setSearchVuale(StringUtil.getParameterLike(cusRecVo.getSearchVuale()));
		}
		if (StringUtil.notTrimEmpty(cusRecVo.getCusType())) {
			String[] cusTypes = cusRecVo.getCusType().split(",");
			if (cusTypes.length > 0) {
				cusRecVo.setCusTypes(cusTypes);
				cusRecVo.setCusType("");
			}
		}
		return this.cusRecDao.selectCustomerList(cusRecVo);
	}

	public boolean checkPhoneNo(String phoneNo, String custId) {
		phoneNo = phoneNo.trim();
		custId = custId.trim();
		PubUser pubUser = new PubUser();
		pubUser.setPhoneNo(phoneNo);
		List<PubUserVo> list2 = this.pubUserFeign.selectByEntity(pubUser);
		if ((list2 != null) && (list2.size() > 0)) {
			pubUser = (PubUser) list2.get(0);
			if (!StringUtil.emptyAndNull(custId)) {
				if (pubUser.getUserId().equals(custId)) {
					return true;
				}
				return false;
			}
			return false;
		}
		return true;
	}

	public CusRec checkCustCode(String custId, String custCode) {
		custId = custId.trim();
		custCode = custCode.trim();

		Example example = new Example(CusRec.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("cusCode", custCode);
		criteria.andNotEqualTo("cusState", "D");
		if (StringUtil.notTrimEmpty(custId)) {
			criteria.andNotEqualTo("cusId", custId);
		}
		List<CusRec> list = selectByExample(example);
		if ((list != null) && (list.size() > 0)) {
			return (CusRec) list.get(0);
		}
		CusRec customer = null;

		PubOrgan pubOrgan = new PubOrgan();
		pubOrgan.setOrganCode(custCode);
		List<PubOrgan> listOrgan = this.pubOrganFeign.selectByEntity(pubOrgan);
		if ((listOrgan != null) && (listOrgan.size() > 0)) {
			PubOrgan organ = (PubOrgan) listOrgan.get(0);
			if ((StringUtil.emptyAndNull(custId))
					|| ((!StringUtil.emptyAndNull(custId)) && (!organ.getOrganId().equals(custId)))) {
				customer = new CusRec();
				customer.setCusName(organ.getOrganName());
				customer.setCusId(organ.getOrganId());
				return customer;
			}
		}
		return customer;
	}

	public CusRec getCustomerByCode(String custCode, String custId, String socCrCode) {
		if ((StringUtil.emptyAndNull(custId)) && (StringUtil.emptyAndNull(custCode))
				&& (StringUtil.emptyAndNull(socCrCode))) {
			this.logger.info("��������������");
			return null;
		}
		CusRec customer = new CusRec();
		if (StringUtil.notTrimEmpty(custCode)) {
			customer.setCusCode(custCode);
		}
		if (StringUtil.notTrimEmpty(custId)) {
			customer.setCusId(custId);
		}
		if (StringUtil.notTrimEmpty(socCrCode)) {
			customer.setSocCrCode(socCrCode);
		}
		customer = (CusRec) selectOne(customer);
		return customer;
	}

	public int freezeOrResumeCustomer(String custId, boolean state) {
		String cusState = "";
		if (state) {
			cusState = "E";
		} else {
			cusState = "U";
		}
		CusRec customer = new CusRec();
		customer.setCusId(custId);
		customer.setCusState(cusState);
		int result = updateNotNull(customer);
		return result;
	}

	public List<CusRec> selectCustomerInfos(CusRecVo cusRecVo) {
		Example example = new Example(CusRec.class);
		Example.Criteria criteria = example.createCriteria();
		if (!StringUtil.emptyAndNull(cusRecVo.getSearchParam())) {
			String likeMemName = StringUtil.getParameterLike(cusRecVo.getSearchParam());
			String likeMemCode = StringUtil.getParameterLike(cusRecVo.getSearchParam());
			criteria.andLike("cusCode", likeMemCode);
			example.or().andLike("cusName", likeMemName);
		}
		return selectByExample(example);
	}

	private void checkSaveCusVo(CusRecVo cusRecVo) {
		CusRec customer = checkCustCode(cusRecVo.getCusId(), cusRecVo.getCusCode());
		if (customer != null) {
			throw new UnCheckMsgException(
					"����������������������" + customer.getCusName() + "��������������������������");
		}
		if (checkPhoneNo(cusRecVo.getContactorPhone(), cusRecVo.getCusId())) {
			throw new UnCheckMsgException("����������������������������������");
		}
	}

	private void setPropety(CusRecVo cusRecVo) {
		cusRecVo.setContactorId(SystemUtil.getUUID());
		cusRecVo.setCusId(SystemUtil.getUUID());
		cusRecVo.setCusState("E");
	}

	private PubUserVo setUserProperty(CusRecVo cusRecVo) {
		PubUserVo user = packUserVo(cusRecVo);
		List<PubRole> roleList = new ArrayList();

		PubDictionary dict = this.pubDictionaryFeign.getDictionaryByCode(cusRecVo.getCusType());
		String roleStr = dict.getExtension2();
		if (StringUtil.notTrimEmpty(roleStr)) {
			String[] roles = roleStr.split(",");
			for (String code : roles) {
				PubRole role = new PubRole();
				role.setRoleCode(code);
				role.setRoleState("E");
				role = this.pubRoleFeign.selectOne(role);
				roleList.add(role);
			}
		}
		user.setRoles(roleList);

		user.setOrganId(cusRecVo.getCusId());
		user.setEntId(cusRecVo.getCusId());
		return user;
	}

	private PubUserVo packUserVo(CusRecVo cusRecVo) {
		PubUserVo user = new PubUserVo();
		user.setUserId(cusRecVo.getContactorId());
		user.setUserName(cusRecVo.getContactorName());
		user.setPhoneNo(cusRecVo.getContactorPhone());
		user.setCertNo(cusRecVo.getCertNo());
		user.setCertType(cusRecVo.getCertType());
		if ("D".equals(cusRecVo.getCusState())) {
			user.setUserState("D");
		} else {
			user.setUserState("E");
		}
		return user;
	}

	private PubOrganVo packOrganVo(CusRecVo cusRecVo) {
		PubOrganVo organVo = new PubOrganVo();
		organVo.setOrganId(cusRecVo.getCusId());
		organVo.setOrganCode(cusRecVo.getCusCode());
		organVo.setOrganName(cusRecVo.getCusName());
		organVo.setShortName(cusRecVo.getCusName());
		if ("D".equals(cusRecVo.getCusState())) {
			organVo.setOrganState("D");
		} else {
			organVo.setOrganState("E");
		}
		organVo.setOrganType("ENT");
		organVo.setSourceCode("EXTERNAL");

		PubDictionary dict = this.pubDictionaryFeign.getDictionaryByCode(cusRecVo.getCusType());
		if (StringUtil.notTrimEmpty(dict.getExtension1())) {
			organVo.setParentCode(dict.getExtension1());
		} else {
			organVo.setParentCode("OG001");
		}
		return organVo;
	}

	@Pagination
	public List<AuthenticatingCusVo> getAuthenticatingCus(PageLimit limit, String[] grpIds, String cusState,
			String cusType, String cusName) {
		if (StringUtil.notEmpty(cusName)) {
			cusName = StringUtil.getParameterLike(cusName);
		}
		String[] cusStates = null;
		if (StringUtil.notEmpty(cusState)) {
			cusStates = cusState.split(",");
		}
		return this.cusRecDao.getAuthenticatingCus(grpIds, cusStates, cusType, cusName);
	}

	@Pagination
	public List<AuthenticatingCusVo> getLastTrialCus(PageLimit limit, String[] grpIds, String cusState, String cusType,
			String cusName) {
		if (StringUtil.notEmpty(cusName)) {
			cusName = StringUtil.getParameterLike(cusName);
		}
		return this.cusRecDao.getLastTrialCus(grpIds, cusState, cusType, cusName);
	}

	public int updateCustomerOptimistically(CusRec customerC, String currentState) {
		return this.cusRecDao.updateCustomerOptimistically(customerC, currentState);
	}

	@Pagination
	public List<CusRec> getUserCusList(PageLimit limit, String searchStr, String cusState) {
		searchStr = StringUtil.getParameterLike(searchStr);
		return this.cusRecDao.getUserCusList(searchStr, cusState, CommonDataUtil.getUserId());
	}

	@Pagination
	public List<CusRec> selectCustomerInviteList(PageLimit limit, CusRec cusRec) {
		return this.cusRecDao.selectCustomerInviteList(cusRec);
	}

	public CusRec selectCustomerInviteById(String cusId) {
		return this.cusRecDao.selectCustomerInviteById(cusId);
	}

	public CusRec selectCustomerByNameTypeSrcId(String cusName, String cusType, String srcId) {
		return this.cusRecDao.selectCustomerByNameTypeSrcId(cusName, cusType, srcId);
	}

	@Pagination
	public List<CusRec> getCooperationAgencyList(PageLimit limit, String searchStr) {
		searchStr = StringUtil.getParameterLike(searchStr);
		return this.cusRecDao.getCooperationAgencyList("FINNER", searchStr);
	}

	public CusRec getCustomerByLoginName(String loginNameOrPhone) {
		return this.cusRecDao.getCustomerByLoginName(loginNameOrPhone);
	}

	public CusRec getCustomerByInviteCode(String inviteCode) {
		PubUserOrgan userOrgan = this.userOrganFeign.getUserOrganByInviteCode(inviteCode);
		CusRec inviter = (CusRec) selectByKey(userOrgan.getEntId());
		return inviter;
	}

	public CusRec checkCusName(String cusId, String cusName) {
		Example example = new Example(CusRec.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("cusName", cusName);
		if (StringUtil.notTrimEmpty(cusId)) {
			criteria.andNotEqualTo("cusId", cusId);
		}
		List<CusRec> cusList = selectByExample(example);
		if ((cusList != null) && (cusList.size() > 0)) {
			return (CusRec) cusList.get(0);
		}
		return null;
	}

	public boolean checkAcctNo(String acctNo, String cusId) {
		Example example = new Example(CusAcct.class);
		Example.Criteria criteria = example.createCriteria();
		if (StringUtil.notTrimEmpty(cusId)) {
			criteria.andNotEqualTo("cusId", cusId);
		}
		criteria.andEqualTo("acctNo", acctNo);
		criteria.andEqualTo("acctType", "0");
		criteria.andEqualTo("acctState", "N");
		List<CusAcct> cusList = this.pubCusAcctService.selectByExample(example);
		if ((cusList != null) && (cusList.size() > 0)) {
			return true;
		}
		return false;
	}

	public CusRec selectCusByIdType(String idType, String idCode) {
		CusRec cusRec = new CusRec();
		switch (idType) {
		case "A":
			cusRec.setOrgCode(idCode);
			break;
		case "B":
			cusRec.setLisNo(idCode);
			break;
		case "C":
			cusRec.setSocCrCode(idCode);
			break;
		}
		return (CusRec) this.cusRecDao.selectOne(cusRec);
	}

	public CusRec getPlatform(String cusId) {
		List<CusRec> recs = this.cusRecDao.getPlatform(cusId, "OPERATOR");
		if ((recs != null) && (recs.size() > 0)) {
			return (CusRec) recs.get(0);
		}
		return null;
	}

	public List<CusRec> selectCusByGrpIdAndTagCode(String grpId, String tagCode) {
		String[] states = { "E", "F" };
		return this.cusRecDao.selectCusByGroupIdAndTagCode(states, grpId, new String[] { tagCode });
	}
}
